<template>
  <div :class="classId">
    <el-select
      popper-class="visualSelect"
      @visible-change="popChange"
      @change="$emit('change', selectValue)"
      v-model="selectValue"
      :placeholder="placeholder"
      :filter-method="filterMethod"
      filterable
      clearable
      :multiple="multiple"
      :disabled="disabled"
    >
      <el-option
        v-for="item in options"
        :key="item[props.value]"
        :label="item[props.label]"
        :value="item[props.value]"
      ></el-option>
    </el-select>
  </div>
</template>
<script>

export default {
    name: 'VirtualSelect',
    model: {
        prop: 'value', // 绑定的值，通过父组件传递
        event: 'update' // 自定义名
    },
    props: {
        defaultFirst: {
            type: Boolean
        },
        list: {
            type: Array,
            default: () => {
                return []
            }
        },
        value: {
            type: [String, Number],
            defaut: ''
        },
        placeholder: {
            type: [String],
            defaut: '请选择'
        },
        multiple: {
            type: Boolean,
            default: true
        },
        disabled: {
            type: Boolean,
            default: false
        },
        props: {
            type: Object,
            default: () => {}
        }
    },
    data () {
        return {
            newList: [],
            classId: 'unlimited',
            selectValue: '',
            options: [],
            domList: null,
            startIndex: 0,
            endIndex: 0,
            maxLength: 8, // 弹出框最大支持8个条目
            itemHeight: 34, // select组件选项高度
            maxHeightom: 0 // 滚动条高度
        }
    },
    watch: {
        selectValue (val) {
            this.$emit('update', val)
            if (!val) {
                this.resetList()
                this.maxHeightDom.style.height = this.newList.length * 3 + 'px'
                this.domList.style.paddingTop = +'px'
            }
        },
        value (val) {
            this.selectValue = val
        },
        list () {
            this.resetList()
            this.init()
        }
    },
    mounted () {
        console.log(this, ' this.props')
        this.resetList()
        this.init()
    },
    methods: {
        addScrollDiv (selectDom) {
            this.maxHeightDom = document.createElement('div')
            this.maxHeightDom.style.width = 0
            selectDom.insertBefore(this.maxHeightDom, this.domList)
        },
        reCacularHeight () {
            this.maxHeightDom.style.height = (this.newList.length + 1) * 34 + 'px'
        },
        resetList (arrys, filter) {
            if (Array.isArray(arrys)) {
                this.newList = arrys.slice(0)
            } else {
                this.newList = this.list.slice(0) // 筛选的数据
            }
            if (!this.multiple && !filter) {
                this.newList.unshift({ [this.props.value]: '', [this.props.label]: '全部' })
            }
            this.options = this.newList.slice(0, filter ? arrys.length : 20) // 显示的数据
        },
        init () {
            // if (this.defaultFirst && this.list.length > 0) {
            //     // 默认第一个
            //     this.selectValue = this.list[0].value
            // }
            this.classId = this.props['label']
            const selectDom = document.querySelector(
                `.${this.classId} .el-select-dropdown .el-select-dropdown__wrap`
            )
            if (selectDom === null) return
            const slectBoxDom = document.querySelector(
                `.${this.classId} .el-select-dropdown__wrap`
            )
            slectBoxDom.style.display = 'flex'
            slectBoxDom.style.flexDirection = 'row'
            this.domList = selectDom.querySelector(
                `.${this.classId} .el-select-dropdown__wrap .el-select-dropdown__list`
            )
            this.addScrollDiv(slectBoxDom) // 添加一个滚动的div
            slectBoxDom.addEventListener('scroll', () => {
                this.reCacularHeight()
                const scrollTop = selectDom.scrollTop
                const startIndex = parseInt(scrollTop / 34)
                const endIndex = startIndex + 19
                this.domList.style.paddingTop = scrollTop + 'px'
                this.options = this.newList.slice(startIndex, endIndex)
            })
        },
        filterMethod (val) {
            if (val) {
                const arrys = this.list.filter((elem) => {
                    return new RegExp(val).test(elem[this.props.label])
                }) // 多这部是性能上优化 请勿合并
                this.resetList(arrys, true)
            } else {
                this.resetList()
            }
            this.reCacularHeight()
        },
        popChange () {
            this.domList.style.paddingTop = 0 + 'px'
            if (!this.selectValue) {
                this.resetList()
            }
            this.reCacularHeight()
        }
    }
}
</script>
<style lang="less" scpoed>
.visualSelect {
  .el-select-dropdown__list {
    width: 100%;
  }
  .el-select-dropdown__wrap {
    height: 255px;
  }
}
</style>
